package com.sky.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;


public class TreeUtils {

    /**
     * 构建树结构（包含数据转换）
     *
     * @param sourceList     原始数据列表（如 Dict）
     * @param mapper         映射函数，将 S 转换为 T（如 Dict → DictVO）
     * @param idGetter       获取 T 的 id
     * @param pidGetter      获取 T 的 pid
     * @param childrenInit   初始化 children 容器
     * @param getChildren    获取 children
     * @param setChildren    设置 children
     * @param <S>            原始数据类型
     * @param <T>            目标树节点类型
     * @return 树形结构的列表
     */
    public static <S, T> List<T> buildTree(
            List<S> sourceList,
            Function<S, T> mapper,
            Function<T, String> idGetter,
            Function<T, String> pidGetter,
            Supplier<List<T>> childrenInit,
            Function<T, List<T>> getChildren,
            BiConsumer<T, List<T>> setChildren
    ) {
        List<T> result = new ArrayList<>();
        Map<String, T> idNodeMap = new HashMap<>();
        // 映射并收集节点并初始化 children
        for (S s : sourceList) {
            T node = mapper.apply(s);
            if (getChildren.apply(node) == null) {
                setChildren.accept(node, childrenInit.get());
            }
            idNodeMap.put(idGetter.apply(node), node);
        }
        // 构建树
        for (T node : idNodeMap.values()) {
            String pid = pidGetter.apply(node);
            if (pid == null || pid.isEmpty() || !idNodeMap.containsKey(pid)) {
                result.add(node);
            } else {
                T parent = idNodeMap.get(pid);
                if (getChildren.apply(parent) == null) {
                    setChildren.accept(parent, childrenInit.get());
                }
                getChildren.apply(parent).add(node);
            }
        }

        return result;
    }
}